﻿using AxIpeDspCtrlLib;
using IpeEngCtrlLib;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using ROIsetting;

namespace SherlockModel
{
    public class LogParam
    {
        /// <summary>
        /// 保存所有OK 、NG日志图片的全路径
        /// </summary>
        public List<string> m_PicLogArray_OK = new List<string>();
        public List<string> m_PicLogArray_NG = new List<string>();
        /// <summary>
        /// 保存Pic图片路径
        /// </summary>
        public string m_strPicLogPath = "";
        /// <summary>
        /// 日志保存的最大数量。
        /// </summary>
        public int m_iMaxPicLogCount = 100;
        public int m_iMaxKeepPicLogDay = 60;
        /// <summary>
        /// 保存图片时，是否保存到一个以日期命名的子文件夹中。
        /// </summary>
        public bool m_bAddSubDateDirectory_PicLog = true;

        /// <summary>
        /// 当前日志的日期，如果增加了一天，则需要将m_PicLogArray_NG清空，否则会将将会把隔天的图片全部删除。
        /// </summary>
        public int m_iCurLogDay = -1;
        /// <summary>
        /// 图片日志定时器。
        /// </summary>
        public System.Timers.Timer m_Timer_PicLog = new System.Timers.Timer();
    }

    public class SherlockModelSystem
    {
        public delegate void runedHandler(SherlockModelSystem sourceEngine, int iID);
        public delegate void runedHandler_2(SherlockModelSystem sourceEngine, int iID, I_EXEC_ERROR euMsg);

        public SherlockModelSystem(int iID)
        {
            ID = iID;
            m_axIpeDspCtrl = new AxIpeDspCtrl();
            m_axIpeDspCtrl.Dock = DockStyle.Fill;
        }
        //每个Sherlock的ID，传递给外部使用。
        public int ID { get; set; }

        //是否保存成功、失败图片
        public bool bSavePic_OK { get; set; }
        public bool bSavePic_NG { get; set; }


        public IpeEngCtrlLib.Engine m_Engine = null;

        /// <summary>
        /// ////////////////////////////////////////////////////////////////////////////////////////
        /// </summary>
        private IpeEngCtrlLib.I_ENG_ERROR m_iReturn;
        private AxIpeDspCtrl m_axIpeDspCtrl;

        public string m_strSherlockPathName = "";
        private string m_strImgWindowName = "";
        System.Timers.Timer m_Timer_SetRoi_0 = new System.Timers.Timer();
        System.Timers.Timer m_Timer_SetRoi_1 = new System.Timers.Timer();

        /// <summary>
        /// 是否重新设置Roi的位置
        /// </summary>
        private bool m_bRestRoi = false;
        private string m_strRoiName = "";

        //
        private LogParam m_LogParam = new LogParam();

        /// <summary>
        　　/// C#按创建时间排序（顺序）
        　　/// </summary>
        　　/// <param name="arrFi">待排序数组</param>
        private void SortAsFileCreationTime(ref FileInfo[] arrFi)
        {
            Array.Sort(arrFi, delegate (FileInfo x, FileInfo y) { return x.CreationTime.CompareTo(y.CreationTime); });
        }

        private void FindAllPicLog_CurDay()
        {
            lock (m_LogParam.m_PicLogArray_OK)
            {
                try
                {
                    string strPicLogPath_OK = Path.GetDirectoryName(CreateNewPicName(true,".bmp"));
                    DirectoryInfo di = new DirectoryInfo(strPicLogPath_OK);

                    FileInfo[] arrFi = di.GetFiles("*.*");
                    SortAsFileCreationTime(ref arrFi);

                    for (int i = 0; i < arrFi.Length; i++)
                    {
                        m_LogParam.m_PicLogArray_OK.Add(arrFi[i].FullName);
                    }
                }
                catch(Exception)
                {

                }

                try
                {
                    string strPicLogPath_NG = Path.GetDirectoryName(CreateNewPicName(false,".bmp"));
                    DirectoryInfo di = new DirectoryInfo(strPicLogPath_NG);

                    FileInfo[] arrFi = di.GetFiles("*.*");
                    SortAsFileCreationTime(ref arrFi);

                    for (int i = 0; i < arrFi.Length; i++)
                    {
                        m_LogParam.m_PicLogArray_NG.Add(arrFi[i].FullName);
                    }
                }
                catch (Exception)
                {

                }
            }
        }
        
        /// <summary>
        /// 删除超数量的日志文件。
        /// </summary>
        private void RemoveOldPicLog(List<string> tmpPicNameList = null)
        {
            if (tmpPicNameList == null || m_LogParam.m_iMaxPicLogCount < 0)
            {
                return;
            }

            lock (tmpPicNameList)
            {
                int iCount = tmpPicNameList.Count() - m_LogParam.m_iMaxPicLogCount;
                if (iCount > 0)
                {
                    for (int i = 0; i < iCount; i++)
                    {
                        string strFile = tmpPicNameList[i];
                        try
                        {
                            File.Delete(strFile);
                        }
                        catch (Exception)
                        {
                        }
                    }

                    tmpPicNameList.RemoveRange(0, iCount);
                }
            }
        }
  

        //
        public AxIpeDspCtrl ImgWindow
        {
            get
            {
                return this.m_axIpeDspCtrl;
            }
        }
        //

        public void CamLive(string windowname = "", bool enable = true)
        {
            try
            {
                if (enable == true)
                {
                    this.m_Engine.SoLiveSet(windowname, 1);
                }
                else
                {
                    this.m_Engine.SoLiveSet(windowname, 0);
                }
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="strDrivers"></param>
        /// <returns></returns>
        public bool CreateVisionSystemEngine(string strDrivers = "")
        {
            this.m_Engine = (Engine)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("F8962A43-6147-4874-9C08-749462A5AC9B")));
            if(strDrivers.Length > 0)
            {
                Type typeFromProgID = Type.GetTypeFromProgID("IpeEngCtrl.Engine.2");
                this.m_Engine = (Engine)Activator.CreateInstance(typeFromProgID);

                this.m_Engine.EngSetAcqIni(strDrivers);
            }

            m_iReturn = this.m_Engine.EngInitialize();
            if (this.m_iReturn != I_ENG_ERROR.I_OK)
            {
                MessageBox.Show("Could not initialize VisionSystem object.", "FATAL ERROR", MessageBoxButtons.OK);
            }

            m_Engine.RunCompleted += new IpeEngCtrlLib._IEngineEvents_RunCompletedEventHandler(OnRunCompleted);
            m_Engine.RunStop += new IpeEngCtrlLib._IEngineEvents_RunStopEventHandler(OnRunStop);
            m_Engine.OnRunError += new IpeEngCtrlLib._IEngineEvents_OnRunErrorEventHandler(OnRunError);

            m_Timer_SetRoi_0 .Elapsed += new System.Timers.ElapsedEventHandler(timer_0_Tick);
            m_Timer_SetRoi_1.Elapsed += new System.Timers.ElapsedEventHandler(this.Timer1_Tick);

            return true;
        }

        public void DeleteVisionSystemEngine()
        {
            if (this.m_Engine != null)
            {
                this.m_Engine.EngTerminate();
                this.m_Engine = null;
            }
        }

        enum enumRoiType
        {
            eu_Rect = 0,
            eu_Rake = 1,
            eu_CircleArea,
            eu_Circle,
            eu_Spoke,

            eu_Unknown 
        }

        enumRoiType GetRoiType(string strRoiName)
        {
            string strRoiType;

            this.m_Engine.RoiTypeGet(this.m_strRoiName, out strRoiType);

            if (strRoiName == "RoiRect" )
            {
                return enumRoiType.eu_Rect;
            }

            if (Module_Var.ROItype == "RoiRake")
            {
                return enumRoiType.eu_Rake;
            }

            if (Module_Var.ROItype == "RoiSpoke")
            {
                return enumRoiType.eu_Spoke;
            }

            if (Module_Var.ROItype == "RoiCircleArea")
            {
                return enumRoiType.eu_CircleArea;
            }

            if (Module_Var.ROItype == "RoiCircle")
            {
                return enumRoiType.eu_Circle;
            }

            return enumRoiType.eu_Unknown;
        }

        /// <summary>
        /// 放大缩小矩形  Rake ROI
        /// </summary>
        /// <param name="strRoi"></param>
        /// <param name="iZoom">正值：放大，负值：缩小</param>
        public void RoiZoom_Rect_Rake(string strRoi,int iZoom)
        {
            enumRoiType roiType = GetRoiType(strRoi);
            if (roiType == enumRoiType.eu_Rect || roiType == enumRoiType.eu_Rake)
            {

                int x = 0, y = 0;
                int iCenter_X = 0, iCenter_Y = 0;
                this.m_Engine.RoiCoordGet(strRoi, 0, out iCenter_X, out iCenter_Y);
                this.m_Engine.RoiCoordGet(strRoi, 1, out x, out y);
                if (iCenter_X > x)
                {
                    iZoom = 0 - iZoom;
                }

                m_Engine.RoiCoordSet(strRoi, 1, x, y + iZoom);
                if (m_axIpeDspCtrl != null)
                {
                    m_axIpeDspCtrl.UpdateDisplay();
                }

                // m_Engine.SoImageUpdate(GlobalCfg.m_SherlockCfg.strImgWindowsName);
            }
        }

        /// <summary>
        /// 放大缩小圆形、圆饼  ROI
        /// </summary>
        /// <param name="strRoi"></param>
        /// <param name="iZoom">正值：放大，负值：缩小</param>
        public void RoiZoom_Circle_CircleArea(string strRoi, int iZoom)
        {
            enumRoiType roiType = GetRoiType(strRoi);
            if (roiType == enumRoiType.eu_Circle || roiType == enumRoiType.eu_CircleArea)
            {

                int x = 0, y = 0;
                int iCenter_X = 0, iCenter_Y = 0;
                this.m_Engine.RoiCoordGet(strRoi, 0, out iCenter_X, out iCenter_Y);
                this.m_Engine.RoiCoordGet(strRoi, 1, out x, out y);
                if (iCenter_X > x)
                {
                    iZoom = 0 - iZoom;
                }

                m_Engine.RoiCoordSet(strRoi, 1, x, y + iZoom);
                if (m_axIpeDspCtrl != null)
                {
                    m_axIpeDspCtrl.UpdateDisplay();
                }

                // m_Engine.SoImageUpdate(GlobalCfg.m_SherlockCfg.strImgWindowsName);
            }
        }

        /// <summary>
        /// 移动ROI
        /// </summary>
        /// <param name="bstrRoi">ROI名称</param>
        /// <param name="nDx">X 方向移到像素个数，正值向右移，负值向左移。</param>
        /// <param name="nDy">Y 方向移到像素个数，正值向上移，负值向下移。</param>
        /// <returns></returns>
        public void RoiMove(string bstrRoi, int nDx, int nDy)
        {
            this.m_Engine.RoiMove(bstrRoi, nDx, nDy);

            if (m_axIpeDspCtrl != null)
            {
                m_axIpeDspCtrl.UpdateDisplay();
            }
        }


        /// <summary>
        ///矩形、Rake  ROI 旋转
        /// </summary>
        /// <param name="strRoi"></param>
        /// <param name="dRotateAngle"></param>
        public void RoiRotation_Rect_Rake(string strRoi,double dRotateAngle)
        {
            enumRoiType roiType = GetRoiType(strRoi);
            if (roiType == enumRoiType.eu_Rect || roiType == enumRoiType.eu_Rake)
            {
                double dCurAngle = 0;

                this.m_iReturn = this.m_Engine.RoiRotationGet(strRoi, out dCurAngle);

                this.m_Engine.RoiRotationSet(strRoi, dCurAngle + dRotateAngle);

                if (m_axIpeDspCtrl != null)
                {
                    m_axIpeDspCtrl.UpdateDisplay();
                }
            }
        }


        public bool InitializeVisionSystemEngine(string strSherlockPath, string strWindowName, AxIpeDspCtrl axIpeDspCtrl = null)
        {
            m_strSherlockPathName = strSherlockPath;
            m_strImgWindowName = strWindowName;
            try
            {
                m_iReturn = m_Engine.InvLoad(strSherlockPath);
                if (m_iReturn != IpeEngCtrlLib.I_ENG_ERROR.I_OK)
                {
                    MessageBox.Show("Could not load investigation.", "FATAL ERROR", MessageBoxButtons.OK);
                    return false;
                }
                if (axIpeDspCtrl != null)
                {
                    m_axIpeDspCtrl = axIpeDspCtrl;
                }
                this.m_axIpeDspCtrl.ConnectEngine(this.m_Engine.GetEngineObj());
                this.m_axIpeDspCtrl.ConnectImgWindow(strWindowName);
                this.m_axIpeDspCtrl.LButtonDown += new _DIpeDspCtrlEvents_LButtonDownEventHandler(this.method_0);
                this.m_axIpeDspCtrl.LButtonUp += new _DIpeDspCtrlEvents_LButtonUpEventHandler(this.method_1);
                this.m_axIpeDspCtrl.MouseMoveEvent += new _DIpeDspCtrlEvents_MouseMoveEventHandler(this.m_axIpeDspCtrl_MouseMoveEvent);

                this.m_axIpeDspCtrl.SetZoom(-1.0);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }

            return true;
        }

        private void timer_0_Tick(object sender, EventArgs e)
        {
            this.m_Engine.RoiMove(m_strRoiName, Module_Var.MouseCurX - Module_Var.MouseIniX, Module_Var.MouseCurY - Module_Var.MouseIniY);
            Module_Var.MouseIniX = Module_Var.MouseCurX;
            Module_Var.MouseIniY = Module_Var.MouseCurY;
            m_axIpeDspCtrl.UpdateDisplay();
            m_axIpeDspCtrl.UseWaitCursor = false;
            m_Timer_SetRoi_0.Enabled = false;
        }

        public void Timer1_Tick(object sender, EventArgs e)
        {
            Array rOIPtsXArray = Module_Var.ROIPtsXArray;
            Array rOIPtsYArray = Module_Var.ROIPtsYArray;
            this.m_Engine.RoiCoordArraySet(m_strRoiName, ref rOIPtsXArray, ref rOIPtsYArray);
            Module_Var.ROIPtsXArray = (int[])rOIPtsXArray;
            Module_Var.ROIPtsYArray = (int[])rOIPtsYArray;
            m_axIpeDspCtrl.UpdateDisplay();
            m_axIpeDspCtrl.UseWaitCursor = false;
            m_Timer_SetRoi_1.Enabled = false;
        }

        private void method_0(object object_0, _DIpeDspCtrlEvents_LButtonDownEvent _DIpeDspCtrlEvents_LButtonDownEvent_0)
        {
            if (this.m_bRestRoi)
            {
                this.m_iReturn = this.m_Engine.RoiRotationGet(this.m_strRoiName, out Module_Var.ROIAngle);
                Array rOIPtsXArray = Module_Var.ROIPtsXArray;
                Array rOIPtsYArray = Module_Var.ROIPtsYArray;
                this.m_Engine.RoiCoordArrayGet(this.m_strRoiName, out rOIPtsXArray, out rOIPtsYArray);
                Module_Var.ROIPtsYArray = (int[])rOIPtsYArray;
                Module_Var.ROIPtsXArray = (int[])rOIPtsXArray;
                this.m_Engine.RoiTypeGet(this.m_strRoiName, out Module_Var.ROItype);
                if (Module_Var.ROItype == "RoiRect" || Module_Var.ROItype == "RoiRake")
                {
                    ROI_Choose.Rect_LButtonClick((double)_DIpeDspCtrlEvents_LButtonDownEvent_0.x, (double)_DIpeDspCtrlEvents_LButtonDownEvent_0.y);
                    if (!Module_Var.ROILTFlag && !Module_Var.ROIRDFlag && !Module_Var.ROIRTFlag && !Module_Var.ROILDFlag && !Module_Var.ROIMoveFlag && !Module_Var.ROIRotateFlag)
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 0);
                    }
                    else
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 1);
                    }
                }
                if (Module_Var.ROItype == "RoiSpoke")
                {
                    ROI_Choose.Spoke_LButtonClick((double)_DIpeDspCtrlEvents_LButtonDownEvent_0.x, (double)_DIpeDspCtrlEvents_LButtonDownEvent_0.y);
                    if (Module_Var.ROIMoveFlag ==false && !Module_Var.ROILTFlag && !Module_Var.ROIRDFlag)
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 1);
                    }
                    else
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 0);
                    }
                }
                if (Module_Var.ROItype == "RoiCircleArea")
                {
                    ROI_Choose.CircleArea_LButtonClick((double)_DIpeDspCtrlEvents_LButtonDownEvent_0.x, (double)_DIpeDspCtrlEvents_LButtonDownEvent_0.y);
                    if (!Module_Var.ROIMoveFlag && !Module_Var.ROILTFlag && !Module_Var.ROIRDFlag && !Module_Var.ROIRTFlag && !Module_Var.ROILDFlag)
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 0);
                    }
                    else
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 1);
                    }
                }
                if (Module_Var.ROItype == "RoiCircle")
                {
                    ROI_Choose.Circle_LButtonClick((double)_DIpeDspCtrlEvents_LButtonDownEvent_0.x, (double)_DIpeDspCtrlEvents_LButtonDownEvent_0.y);
                    if (!Module_Var.ROIMoveFlag && !Module_Var.CirPtFlag)
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 0);
                    }
                    else
                    {
                        this.m_Engine.RoiSelectedSet(this.m_strRoiName, 1);
                    }
                }
                this.m_axIpeDspCtrl.UpdateDisplay();
            }
        }

        private void method_1(object object_0, _DIpeDspCtrlEvents_LButtonUpEvent _DIpeDspCtrlEvents_LButtonUpEvent_0)
        {
            if (this.m_bRestRoi)
            {
                Module_Var.ROIMoveFlag = false;
                Module_Var.ROILTFlag = false;
                m_Timer_SetRoi_0.Enabled = false;
                Module_Var.ROIRDFlag = false;
                Module_Var.ROIRotateFlag = false;
                Module_Var.ROIRTFlag = false;
                Module_Var.ROILDFlag = false;
                Module_Var.CirPtFlag = false;
                m_Timer_SetRoi_1.Enabled = false;
                Cursor.Current = Cursors.Arrow;
            }
        }

        private void m_axIpeDspCtrl_MouseMoveEvent(object object_0, _DIpeDspCtrlEvents_MouseMoveEvent _DIpeDspCtrlEvents_MouseMoveEvent_0)
        {
            if (this.m_bRestRoi)
            {
                this.m_iReturn = this.m_Engine.RoiRotationGet(this.m_strRoiName, out Module_Var.tempROIAngle);
                Array rOIPtsXArray = Module_Var.ROIPtsXArray;
                Array rOIPtsYArray = Module_Var.ROIPtsYArray;
                this.m_Engine.RoiCoordArrayGet(this.m_strRoiName, out rOIPtsXArray, out rOIPtsYArray);
                Module_Var.ROIPtsYArray = (int[])rOIPtsYArray;
                Module_Var.ROIPtsXArray = (int[])rOIPtsXArray;
                this.m_Engine.RoiTypeGet(this.m_strRoiName, out Module_Var.ROItype);
                if (Module_Var.ROItype == "RoiRect" || Module_Var.ROItype == "RoiRake")
                {
                    Mouse_Move.Rect_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                    if (Module_Var.ROIMoveFlag)
                    {
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeAll;
                        m_Timer_SetRoi_0.Enabled = true;
                    }
                    if (Module_Var.ROILTFlag || Module_Var.ROIRDFlag)
                    {
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeNWSE;
                        m_Timer_SetRoi_1.Enabled = true;
                    }
                    if (Module_Var.ROIRotateFlag)
                    {
                        Mouse_Move.Rect_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                        this.m_Engine.RoiRotationSet(this.m_strRoiName, Module_Var.ROIAngle + Module_Var.tempIniRotateAngle);
                        this.m_axIpeDspCtrl.UpdateDisplay();
                    }
                }
                if (Module_Var.ROItype == "RoiSpoke")
                {
                    Mouse_Move.Spoke_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                    if (Module_Var.ROIMoveFlag)
                    {
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeAll;
                        m_Timer_SetRoi_0.Enabled = true;
                    }
                    if (Module_Var.ROILTFlag || Module_Var.ROIRDFlag)
                    {
                        Mouse_Move.Spoke_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                        m_Timer_SetRoi_1.Enabled = true;
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeNWSE;
                    }
                }
                if (Module_Var.ROItype == "RoiCircleArea")
                {
                    Mouse_Move.CircleArea_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                    if (Module_Var.ROIMoveFlag)
                    {
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeAll;
                        m_Timer_SetRoi_0.Enabled = true;
                    }
                    if (Module_Var.ROILTFlag || Module_Var.ROIRDFlag || Module_Var.ROIRTFlag || Module_Var.ROILDFlag)
                    {
                        Mouse_Move.CircleArea_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                        m_Timer_SetRoi_1.Enabled = true;
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeNWSE;
                    }
                }
                if (Module_Var.ROItype == "RoiCircle")
                {
                    Mouse_Move.Circle_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                    if (Module_Var.ROIMoveFlag)
                    {
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeAll;
                        m_Timer_SetRoi_0.Enabled = true;
                    }
                    if (Module_Var.CirPtFlag)
                    {
                        Mouse_Move.Circle_MouseMove((double)_DIpeDspCtrlEvents_MouseMoveEvent_0.x, (double)_DIpeDspCtrlEvents_MouseMoveEvent_0.y);
                        m_Timer_SetRoi_1.Enabled = true;
                        this.m_axIpeDspCtrl.UseWaitCursor = true;
                        Cursor.Current = Cursors.SizeNWSE;
                    }
                }
            }
        }


        private void OnRunCompleted()
        {
            if (OnSherlockRunCompleted != null)
            {
                OnSherlockRunCompleted(this,ID);
            }
        }

        private void OnRunError(I_EXEC_ERROR nError)
        {
            if (OnSherlockRunError != null)
            {
                OnSherlockRunError(this, ID,  nError);
            }
        }

        private void OnRunStop()
        {
            if (OnSherlockRunError != null)
            {
                OnSherlockRunStop(this, ID);
            }
        }



        public bool ContinuousRun()
        {
            m_iReturn = m_Engine.InvModeSet(IpeEngCtrlLib.I_MODE.I_EXE_MODE_CONT);
            if (m_iReturn == I_ENG_ERROR.I_OK)
            {
                return true;
            }

            return false;
        }

        public bool OnceRun()
        {
            m_iReturn = m_Engine.InvModeSet(IpeEngCtrlLib.I_MODE.I_EXE_MODE_ONCE);
            if (m_iReturn == I_ENG_ERROR.I_OK)
            {
                return true;
            }

            return false;
        }

        public void HaltInv()
        {
            IpeEngCtrlLib.I_MODE iCurrMode;

            m_iReturn = m_Engine.InvModeSet(IpeEngCtrlLib.I_MODE.I_EXE_MODE_HALT); // halt inspection after current inspection is finished
            Application.DoEvents();
            m_iReturn = m_Engine.InvModeGet(out iCurrMode);

            int iLoopCount = 0;

            while (iCurrMode != IpeEngCtrlLib.I_MODE.I_EXE_MODE_HALT && iLoopCount < 200) //stay in loop until Halt is complete
            {
                Application.DoEvents();

                iLoopCount++;
                Thread.Sleep(10);

                m_iReturn = m_Engine.InvModeGet(out iCurrMode);
            }
            if (iLoopCount >= 200)
            {
                m_Engine.CamAcqAbort();
            }
        }

        public void Stop()
        {
            HaltInv();
        }

        public bool VarGetBool(string bstrName, bool bDefault)
        {
            bool bRet = false;
            m_iReturn = m_Engine.VarGetBool(bstrName, out bRet);
            if (m_iReturn != I_ENG_ERROR.I_OK)
            {
                bRet = bDefault;
            }

            return bRet;
        }
        public double VarGetDouble(string bstrName, double dDefault)
        {
            double dRet = 0.0;
            m_iReturn = m_Engine.VarGetDouble(bstrName, out dRet);
            if (m_iReturn != I_ENG_ERROR.I_OK)
            {
                dRet = dDefault;
            }

            return dRet;
        }

        public string VarGetString(string bstrName, string strDefault)
        {
            string strRet = "";
            m_iReturn = m_Engine.VarGetString(bstrName, out strRet);
            if (m_iReturn != I_ENG_ERROR.I_OK)
            {
                strRet = strDefault;
            }

            return strRet;
        }
        public bool VarSetBool(string bstrName, bool val)
        {
            bool bRet = false;

            m_iReturn = m_Engine.VarSetBool(bstrName, val);
            if (m_iReturn != I_ENG_ERROR.I_OK)
            {
                bRet = false;
            }
            else
            {
                bRet = true;
            }

            return bRet;
        }
        public bool VarSetDouble(string bstrName, double val)
        {
            bool bRet = false;

            m_iReturn = m_Engine.VarSetDouble(bstrName, val);
            if (m_iReturn != I_ENG_ERROR.I_OK)
            {
                bRet = false;
            }
            else
            {
                bRet = true;
            }

            return bRet;
        }
        public bool VarSetString(string bstrName, string val)
        {
            bool bRet = false;

            m_iReturn = m_Engine.VarSetString(bstrName, val);
            if (m_iReturn != I_ENG_ERROR.I_OK)
            {
                bRet = false;
            }
            else
            {
                bRet = true;
            }

            return bRet;
        }

        public Array VarGetParamValue(I_VAR_TYPE valuestyle, string valuename)
        {
            Array array = null;
            Array result;
            try
            {
                switch (valuestyle)
                {
                    case I_VAR_TYPE.I_VAR_BOOL_ARRAY:
                        m_iReturn = m_Engine.VarGetBoolArray(valuename, out array);
                        break;
                    case I_VAR_TYPE.I_VAR_DOUBLE_ARRAY:
                        m_iReturn = m_Engine.VarGetDoubleArray(valuename, out array);
                        break;
                    case I_VAR_TYPE.I_VAR_STRING_ARRAY:
                        m_iReturn = m_Engine.VarGetStringArray(valuename, out array);
                        break;
                    case I_VAR_TYPE.I_VAR_POINT_ARRAY:
                        m_iReturn = m_Engine.VarGetPointArray(valuename, out array);
                        break;
                    case I_VAR_TYPE.I_VAR_LINE_ARRAY:
                        m_iReturn = m_Engine.VarGetLineArray(valuename, out array);
                        break;
                }
                if (m_iReturn != I_ENG_ERROR.I_OK)
                {
                    MessageBox.Show(valuename + "调用出错");
                }
                result = array;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                result = array;
            }
            return result;
        }

        public bool VarSetParamValue(I_VAR_TYPE valuestyle, string valuename, object value)
        {
            bool result;
            try
            {
                switch (valuestyle)
                {
                    case I_VAR_TYPE.I_VAR_BOOL:
                        m_iReturn = m_Engine.VarSetBool(valuename, (bool)value);
                        break;
                    case I_VAR_TYPE.I_VAR_INT:
                        break;
                    case I_VAR_TYPE.I_VAR_DOUBLE:
                        m_iReturn = m_Engine.VarSetDouble(valuename, (double)value);
                        break;
                    case I_VAR_TYPE.I_VAR_STRING:
                        m_iReturn = m_Engine.VarSetString(valuename, (string)value);
                        break;
                    case I_VAR_TYPE.I_VAR_POINT:
                        {
                            I_POINT i_POINT = (I_POINT)value;
                            m_iReturn = m_Engine.VarSetPoint(valuename, ref i_POINT);
                            break;
                        }
                    case I_VAR_TYPE.I_VAR_LINE:
                        {
                            I_LINE i_LINE = (I_LINE)value;
                            m_iReturn = m_Engine.VarSetLine(valuename, ref i_LINE);
                            break;
                        }
                    default:
                        switch (valuestyle)
                        {
                            case I_VAR_TYPE.I_VAR_BOOL_ARRAY:
                                {
                                    Array array = (Array)value;
                                    m_iReturn = m_Engine.VarSetBoolArray(valuename, ref array);
                                    break;
                                }
                            case I_VAR_TYPE.I_VAR_DOUBLE_ARRAY:
                                {
                                    Array array2 = (Array)value;
                                    m_iReturn = m_Engine.VarSetDoubleArray(valuename, ref array2);
                                    break;
                                }
                            case I_VAR_TYPE.I_VAR_STRING_ARRAY:
                                {
                                    Array array3 = (Array)value;
                                    m_iReturn = m_Engine.VarSetStringArray(valuename, ref array3);
                                    break;
                                }
                            case I_VAR_TYPE.I_VAR_POINT_ARRAY:
                                {
                                    Array array4 = (Array)value;
                                    m_iReturn = m_Engine.VarSetPointArray(valuename, ref array4);
                                    break;
                                }
                            case I_VAR_TYPE.I_VAR_LINE_ARRAY:
                                {
                                    Array array5 = (Array)value;
                                    m_iReturn = m_Engine.VarSetLineArray(valuename, ref array5);
                                    break;
                                }
                        }
                        break;
                }
                if (m_iReturn != I_ENG_ERROR.I_OK)
                {
                    MessageBox.Show(valuename + "调用出错");
                    result = false;
                }
                else
                {
                    result = true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                result = false;
            }
            return result;
        }

        public void LoadImage(string imgwindow, string filepath)
        {
            try
            {
                m_iReturn = m_Engine.SoImageLoad(imgwindow, filepath);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        public void SaveIVS(string filepath = "")
        {
            try
            {
                if (filepath.Length < 1)
                {
                    m_iReturn = m_Engine.InvSave(m_strSherlockPathName);
                }
                else
                {
                    m_iReturn = m_Engine.InvSave(filepath);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private string CreateNewPicName(bool bOK,string strExa)
        {
            Random rd = new Random();

            string strDate = DateTime.Now.Date.ToString("yyyyMMdd");
            string strTime = DateTime.Now.ToString("HH-mm-ss");
            int iRd = rd.Next(1000, 10000);

            string strName,strResult = "OK\\";
            if(bOK == false)
            {
                strResult = "NG\\";
            }
            
            if (m_LogParam.m_bAddSubDateDirectory_PicLog == true)
            {
                strName = strDate + "\\" + strResult + strTime + "_" + iRd;
            }
            else
            {
                strName = strResult + strDate + "_" + strTime + "_" + iRd;
            }

            return m_LogParam.m_strPicLogPath + strName + strExa;
        }

        private void SaveImage(List<string> PicLogPath,string imgwindow, bool bOK, bool bGraphiclabel,string strExa)
        {
            if (m_LogParam.m_strPicLogPath.Length < 1)
            {
                return;
            }
            
            string strName = "";
            strName = CreateNewPicName(bOK, strExa);
            lock (PicLogPath)
            {
                PicLogPath.Add(strName);
                RemoveOldPicLog(PicLogPath);
            }

            string strPath = Path.GetDirectoryName(strName);
            if (!Directory.Exists(strPath))
            {
                Directory.CreateDirectory(strPath);
            }

            if (bGraphiclabel == true)
            {
                m_Engine.SoImageSaveWithGraphics(imgwindow, strName);
            }
            else
            {
                m_Engine.SoImageSave(imgwindow, strName);
            }
        }

        private void Timers_PicLog_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            DateTime time2 = DateTime.Now;
            if (time2.Day != m_LogParam.m_iCurLogDay)
            {
                m_LogParam.m_iCurLogDay = time2.Day;

                //不再计数。
                lock (m_LogParam.m_PicLogArray_OK)
                {
                    m_LogParam.m_PicLogArray_OK.Clear();
                }
                lock(m_LogParam.m_PicLogArray_NG)
                {
                    m_LogParam.m_PicLogArray_NG.Clear();
                }

                //删除过期的日志文件夹。
                string[] subfolders = null;
                try
                {
                    subfolders = Directory.GetDirectories(m_LogParam.m_strPicLogPath);
                }
                catch (Exception)
                {
                    return;
                }

                if (subfolders == null || subfolders.Length < 1)
                {
                    return;
                }

                foreach (string s in subfolders)
                {
                    try
                    {
                        DirectoryInfo info = new DirectoryInfo(s);
                        string name = info.Name;//获取当前路径最后一级文件夹名称
                        IFormatProvider ifp = new CultureInfo("zh-CN", true);
                        DateTime folderTime = DateTime.ParseExact(name, "yyyyMMdd", ifp);
                        TimeSpan subTime =  time2 - folderTime;

                        if (subTime.TotalDays > m_LogParam.m_iMaxKeepPicLogDay)
                        {
                            Directory.Delete(s, true);
                        }
                    }
                    catch(Exception )
                    {

                    }
                }
            }            
        }

        public void SaveImage_bmp(string imgwindow,bool bOK, bool bGraphiclabel = false)
        {
            if (bOK == true)
            {
                SaveImage(m_LogParam.m_PicLogArray_OK,imgwindow, bOK, bGraphiclabel, ".bmp");
            }
            else
            {
                SaveImage(m_LogParam.m_PicLogArray_NG, imgwindow, bOK, bGraphiclabel, ".bmp");
            }
        }

        public void SaveImage_jpeg(string imgwindow, bool bOK, bool bGraphiclabel = false)
        {
            if (bOK == true)
            {
                SaveImage(m_LogParam.m_PicLogArray_OK, imgwindow, bOK, bGraphiclabel, ".jpg");
            }
            else
            {
                SaveImage(m_LogParam.m_PicLogArray_NG, imgwindow, bOK, bGraphiclabel, ".jpg");
            }
        }

        /// <summary>
        /// iMaxPicCount：-1表示不删除。
        /// iMaxKeepPicDay:最长可以保存多长时间。
        /// bAddSubDateDirectory:是否以日期做为子目录。
        /// </summary>
        /// <param name="Path"></param>
        /// <returns></returns>
        public void SetPicLogParam(string strPath, bool bAddSubDateDirectory,bool bSavePic_OK, bool bSavePic_NG, int iMaxPicCount = -1,int iMaxKeepPicDay = -1)
        {
            this.bSavePic_NG = bSavePic_NG;
            this.bSavePic_OK = bSavePic_OK;

            m_LogParam.m_iMaxPicLogCount = iMaxPicCount;
            m_LogParam.m_iMaxKeepPicLogDay = iMaxKeepPicDay;

            m_LogParam.m_bAddSubDateDirectory_PicLog = bAddSubDateDirectory;
            m_LogParam.m_strPicLogPath = strPath;
            if (m_LogParam.m_strPicLogPath.Length < 1)
            {
                m_LogParam.m_strPicLogPath = Application.StartupPath + "\\PicLog";
            }
            m_LogParam.m_strPicLogPath = m_LogParam.m_strPicLogPath.TrimEnd('\\')+"\\";

            FindAllPicLog_CurDay();

            RemoveOldPicLog(m_LogParam.m_PicLogArray_NG);
            RemoveOldPicLog(m_LogParam.m_PicLogArray_OK);

            //只有在设置保存图片时间和增加日期文件夹的情况下，才开启Timer。
            //如果不增加日期文件夹，则由iMaxPicCount来控制。
            if (iMaxKeepPicDay > 0 && bAddSubDateDirectory == true)
            {
                m_LogParam.m_Timer_PicLog.Enabled = true;
                m_LogParam.m_Timer_PicLog.Interval = 1000;
                m_LogParam.m_Timer_PicLog.Elapsed += new System.Timers.ElapsedEventHandler(Timers_PicLog_Elapsed);
            }
        }

        /// <summary>
        /// 重新设置Roi的位置。
        /// 
        /// </summary>
        /// <param name="strm_strRoiName"></param>
        public void BeginRestRoi(string strm_strRoiName)
        {
            m_bRestRoi = true;
            m_strRoiName = strm_strRoiName;
        }
        /// <summary>
        /// 完成设置Roi的位置
        /// </summary>
        public void EndRestRoi()
        {
            m_bRestRoi = false;
            m_strRoiName = "";
        }

        public event SherlockModelSystem.runedHandler OnSherlockRunCompleted = null;
        public event SherlockModelSystem.runedHandler OnSherlockRunStop = null;
        public event SherlockModelSystem.runedHandler_2 OnSherlockRunError = null;
    }
}
